﻿using System;
using System.Collections;
using System.IO;
using System.Threading;

namespace PuppetMaster
{
    public class Parser
    {
        private PuppetMaster _puppetMaster;

        private int _startedServers;

        public Parser( PuppetMaster pm )
        {
            _puppetMaster = pm;
            _startedServers = 0;

        }

        public void ParseFile( string path )
        {
            _startedServers = 0;

            StreamReader s = File.OpenText( path );
            String read = null;
            while( ( read = s.ReadLine( ) ) != null )
            {
                Execute( read );
                Thread.Sleep( 200 );
            }
            s.Close( );
        }

        public void ParseString( string s, bool gui )
        {
            _startedServers = 0;

            StringReader reader = new StringReader( s );
            String read = null;
            while( ( read = reader.ReadLine( ) ) != null )
            {
                Execute( read, gui );
                Thread.Sleep( 200 );
            }
            reader.Close( );
        }

        private void Execute( String command, bool gui = true )
        {
            String[ ] splits = command.Split( ' ' );

            if( splits[ 0 ] == "connect" )
            {
                if( splits[ 1 ].Contains( "central-" ) )
                {                  
                    int id = Int32.Parse( splits[ 1 ][ 8 ].ToString( ) );

                    //Ignoring port on the command
                    int port = -1;
                    switch (id)
                    {
                        case 1:
                            port = 5001;
                            break;
                        case 2:
                            port = 5002;
                            break;
                        case 3:
                            port = 5003;
                            break;
                        case 4:
                            port = 5004;
                            break;
                    }

                    _puppetMaster.ConnectServer( id, "127.0.0.1:" + port, gui );

                    if( _startedServers == 0 )
                    {
                        Thread.Sleep( 25000 );
                    }
                    else
                    {
                        Thread.Sleep( 2000 );
                    }
                    _startedServers++;
                }
                else
                {
                    _puppetMaster.ConnectClient( splits[ 1 ], splits[ 2 ], gui );
                }
            }

            else if( splits[ 0 ] == "disconnect" )
            {
                Console.WriteLine(splits[1]);
                if( splits[ 1 ].Contains( "central-" ) )
                {
                    int id = Int32.Parse(splits[1][8].ToString());
                    int port = -1;
                    switch (id)
                    {
                        case 1:
                            port = 5001;
                            break;
                        case 2:
                            port = 5002;
                            break;
                        case 3:
                            port = 5003;
                            break;
                        case 4:
                            port = 5004;
                            break;
                    }
                    _puppetMaster.DisconectServer("127.0.0.1:" + port);
                }
                else
                {
                    _puppetMaster.DisconectClient( splits[ 2 ] );
                }
            }

            else if( splits[ 0 ] == "reservation" )
            {
                string reservationName;
                string initiator;
                string invitedUsers;
                ArrayList slotList = new ArrayList( );

                string parsedCommand = command.Replace( " ", "" );
                parsedCommand = parsedCommand.Substring( 11 );
                parsedCommand = parsedCommand.Replace( "{", "" );
                parsedCommand = parsedCommand.Replace( "}", "" );

                string[ ] reservationSplit = parsedCommand.Split( ';' );

                reservationName = reservationSplit[ 0 ];

                string[ ] usersSplit = reservationSplit[ 1 ].Split( ',' );
                initiator = usersSplit[ 0 ];

                if( usersSplit.Length == 1 )
                    invitedUsers = usersSplit[ 0 ];
                else
                    invitedUsers = reservationSplit[ 1 ].Remove( 0, initiator.Length + 1 );
                //invitedUsers = reservationSplit[1];

                string[ ] slotsSplit = reservationSplit[ 2 ].Split( ',' );
                foreach( string s in slotsSplit )
                {
                    slotList.Add( Int32.Parse( s ) );
                }

                _puppetMaster.BeginReservation( initiator, slotList, invitedUsers, reservationName );
            }

            else if( splits[ 0 ] == "readCalendar" )
            {
                _puppetMaster.ReadCalendar( splits[ 2 ], splits[ 1 ] );
            }

            else if( splits[ 0 ] == "wait" )
            {
                int seconds = Int32.Parse( splits[ 1 ] );
                Thread.Sleep( seconds * 1000 );
            }

            else if( splits[ 0 ] == "shutdown" )
            {
                _puppetMaster.KillAllClients( );
                _puppetMaster.KillAllServers( );
                _startedServers = 0;
            }
        }
    }
}